﻿using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Serialization;

namespace WindowsAPI.PInvoke
{
    public partial class LibraryFileInfo : FileSystemInfo, IDisposable
    {
        private readonly IntPtr f_Handle;
        private readonly FileInfo f_File;

        public IntPtr Handle { get { return f_Handle; } }

        public override string Name { get { return f_File.Name; } }
        public override string FullName { get { return f_File.FullName; } }
        public override bool Exists { get { return f_File.Exists; } }

        public LibraryFileInfo(string FileName)
        {
            f_File = new FileInfo(FileName);
            f_Handle = API.LoadWin32Library(FileName);
        }

        #region FileInfo

        public override void Delete() { f_File.Delete(); }
        public override int GetHashCode() { return f_File.GetHashCode(); }

        public override bool Equals(object obj) { return f_File.Equals(obj); }

        public override string ToString() { return f_File.ToString(); }

        public override ObjRef CreateObjRef(Type requestedType) { return f_File.CreateObjRef(requestedType); }

        public override object InitializeLifetimeService() { return f_File.InitializeLifetimeService(); }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            f_File.GetObjectData(info, context);
        }

        public void Dispose()
        {
            if(f_Handle != IntPtr.Zero)
                API.FreeLibrary(f_Handle);
        }

        #endregion

        public Delegate GetFunction(string Name, Type t)
        {
            var handle = API.GetProcAddress(f_Handle, Name);
            if(handle == IntPtr.Zero)
                throw new Win32Exception(Marshal.GetLastWin32Error());
            return API.GetFunction(handle, t);
        }
    }
}
